feat: add solution pages with a11y and SEO compliance#134
Open
sinduri-g wants to merge 8 commits into
Open
Conversation
- New route `/adventures/:id/levels/:levelId/solution` with static prerendering - SolutionDetail.tsx: narrative hero, collapsible step cards, sidebar TOC, Codespaces card, outro ending - Solution data pipeline: types.ts, generate-solutions.mjs, barrel index.ts; `prebuild` now runs both generators - Beginner solution for Echoes Lost in Orbit with step-by-step YAML walkthrough and solution images (WebP) - ChallengeDetail: "Solution walkthrough" link surfaced at the bottom of each level - A11y: tabindex=-1 on details elements for fragment-nav focus movement; motion-reduce:transition-none on summary chevron; aria-live region for copy confirmation; blockquote replaced with div[role=note] - SEO: buildSitemapBody emits solution URLs when authored solution files exist; llms.txt includes solution page links; BreadcrumbList JSON-LD on solution pages - Project commands migrated from .claude/skills/ to .claude/commands/; add-solution command added Signed-off-by: Sinduri Guntupalli <sinduri.guntupalli@dynatrace.com>
Contributor
|
Adds an optional contributor field to the Solution type, rendered as a ContributorBadge (labelled "Solution Contributor") in the hero alongside the difficulty badge. Wired up for the Broken Echoes beginner solution with Katharina Sick. Signed-off-by: Sinduri Guntupalli <sinduri.guntupalli@dynatrace.com>
…tests - Check SOLUTIONS registry in ChallengeDetail loader so the walkthrough link only appears when a solution file has been authored, not just when the deadline has passed - Add .catch() to clipboard writeText in SolutionDetail to surface failures instead of silently swallowing them - Tighten prerender assertion from "Solution" to "Solution:" so the check only passes when a real authored solution title is rendered, not a fallback "Not Found" or locked state - Update generate-solutions.mjs template to emit the same stricter assertion for future solutions Signed-off-by: Sinduri Guntupalli <sinduri.guntupalli@dynatrace.com>
- Replace floating language label + absolute copy button with a header bar (label right-aligned, copy button in the pre area via md-copy-btn) so they never overlap at any viewport width - Add overflow-wrap: break-word to md-content and md-inline inline code to prevent long file paths overflowing on mobile - Show "What Was Fixed" step nav above the context section on mobile (lg:hidden in main column, hidden lg:block in sidebar) - Fix prerender tests to read the solution HTML once in beforeAll - Move contributor badge below intro text in SolutionHero - Aggregate further reading links de-duped into a sidebar card - Remove collapsible wrapper from context section (always-open) - Update add-solution.md, ADVENTURES.md, and styleguide.md to reflect new contributor, outro, and further reading conventions Signed-off-by: Sinduri Guntupalli <sinduri.guntupalli@dynatrace.com>
- Move `furtherReading` from `SolutionStep` to top-level `Solution` type;
remove per-step aggregation/dedup in favour of a single authored list
- Add `loader` to `SolutionDetail`; `meta()` now uses loader data via
`MetaFunction<typeof loader>`, eliminating duplicate `SOLUTIONS.find` calls
- Replace `<h2>` inside `<summary>` elements with `<span>` to fix unreliable
AT heading navigation through `<details>/<summary>`
- Fix `BlockRenderer` and `TakeawaysList` index keys (`${type}-${i}` and
`key={item}` respectively)
- Fix `patchRegion` silent failure: missing region markers now abort with
an error instead of no-op
- Add `--validate-only` flag to `generate-solutions.mjs` and
`generate:solutions:validate` npm script
- Fix `beforeAll` missing from vitest import in `prerender.test.ts`; replace
hardcoded contributor/outro assertions with `SOLUTIONS` data lookups
- Add `src/test/solutionDetail.test.tsx`: page-state tests and `CodeBlock`
copy-button tests (clipboard call, Copied state, 1500ms revert)
Signed-off-by: Sinduri Guntupalli <sinduri.guntupalli@dynatrace.com>
- Replace em dashes in aria-labels with colon/comma separators (AT reads — as "dash") - Extract isSolutionUnlocked() to utils.ts; use in both ChallengeDetail and SolutionDetail loaders - Rename loader field available → solutionUnlocked for clarity - Add role="list" to solution steps <ol> (Tailwind preflight strips VoiceOver list semantics) - Promote step titles from <span> to <h3> so heading-key navigation reaches them - Replace <p> with <h2> for the solution walkthrough promo in ChallengeDetail - Remove StepFooter passthrough; move null-guard into TakeawaysList - Guard SolutionHero backstory div so empty role="note" is never rendered - Fix topic pill and copy button touch targets to meet WCAG 2.5.8 (24px minimum) - Use ReturnType<typeof loader> for useLoaderData generic in ChallengeDetail - Fix ArrowRight icon size from 13 to 14 - Update all test fixtures to use solutionUnlocked and include deadline field Signed-off-by: Sinduri Guntupalli <sinduri.guntupalli@dynatrace.com>
…t-in-orbit - Add intermediate solution (The Silent Canary): three bugs in the AnalysisTemplate fixed step by step — wrong Prometheus service name, inverted success condition, and missing ready-containers query - Add expert solution (Hyperspace Operations & Transport): OpenTelemetry Collector configuration walkthrough and three-metric canary analysis - Add 12 WebP images for both levels - Fix beginner solution: split kubectl commands with intermediate explanation, add missing apply command after auto-sync fix, restore self-healing outcome sentence, correct two-apps alt text - Update add-solution command: remove two-takeaway cap, preserve all source takeaways; add note to not drop explanatory prose - Generator patches: sitemap, llms.txt, smoke tests, prerender tests, SEO tests, react-router config, solutions index Signed-off-by: Sinduri Guntupalli <sinduri.guntupalli@dynatrace.com>
- Guard navigator.clipboard with optional chaining to avoid synchronous TypeError in non-secure contexts - Add explicit LoaderData return type to loader function - Fix canonical URL trailing slash to match sitemap (/solution/) - Lowercase overline label source text (CSS text-transform: uppercase handles display) Signed-off-by: Sinduri Guntupalli <sinduri.guntupalli@dynatrace.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
/adventures/:id/levels/:levelId/solutionwith static prerenderingprebuildnow runs both generatorsType of change
featnew featurefixbug fixrefactorno behavior changedocs/chore/config/perf/style/securityManual checks